﻿using System;
using System.Windows.Forms;

namespace Ellanet
{
    public partial class Host : Form // KryptonForm
    {
        private string _guiXmlPath = null;
        private string _hostName = null;
        private string _vmrunPath = null;
        private ErrorProvider ep = new ErrorProvider();

        public Host(string hostName, string guiXmlPath, string vmrunPath)
        {
            InitializeComponent();
            _guiXmlPath = guiXmlPath;
            _hostName = hostName;
            _vmrunPath = vmrunPath;
            this.Load += new EventHandler(AddHost_Load);
            hostComboBox.SelectedIndexChanged += new EventHandler(hostComboBox_SelectedIndexChanged);
            addButton.Click += new EventHandler(addButton_Click);
            localhostCheckBox.CheckedChanged += new EventHandler(localhostCheckBox_CheckedChanged);
            hostTextBox.TextChanged += new EventHandler(hostTextBox_TextChanged);
            overrideCheckBox.CheckedChanged += new EventHandler(overrideCheckBox_CheckedChanged);
            portTextBox.TextChanged += new EventHandler(portTextBox_TextChanged);
            testButton.Click += new EventHandler(testButton_Click);
            newCredentialsButton.Click += new EventHandler(newCredentialsButton_Click);
        }

        void newCredentialsButton_Click(object sender, EventArgs e)
        {
            Credentials cred = new Credentials(null, _guiXmlPath);

            if (cred.ShowDialog() == DialogResult.OK)
            {
                UpdateCredentialsList();
                credentialsComboBox.Text = cred.CredentialsName;
            }
        }

        void testButton_Click(object sender, EventArgs e)
        {
            if (ValidateForm())
            {
                string message = null;
                string username = null;
                string password = null;
                new vmrunGUIXmlWrapper(_guiXmlPath).GetCredentials(credentialsComboBox.Text, out username, out password);

                if (new vmrunCLIWrapper(_vmrunPath, new vmrunInfoXmlWrapper().ConvertFriendlyNameToType(hostComboBox.Text), argumentsTextBox.Text, username, password, null, null, null).TestHostConnection(out message))
                {
                    MessageBox.Show(String.Format("Successfully connected to {0}.", nameTextBox.Text), "Host Connection Successful", MessageBoxButtons.OK, MessageBoxIcon.Information);
                }
                else
                {
                    MessageBox.Show(String.Format("Error connecting to {0}.\r\r{1}", nameTextBox.Text, message), "Could Not Connect To Host", MessageBoxButtons.OK, MessageBoxIcon.Error);
                }
            }
        }

        void portTextBox_TextChanged(object sender, EventArgs e)
        {
            BuildURL();
        }

        void overrideCheckBox_CheckedChanged(object sender, EventArgs e)
        {
            if (overrideCheckBox.Checked)
            {
                argumentsTextBox.ReadOnly = false;
                argumentsTextBox.Select();
            }
            else
            {
                argumentsTextBox.ReadOnly = true;
            }

            BuildURL();
        }

        void hostTextBox_TextChanged(object sender, EventArgs e)
        {
            BuildURL();
        }

        void localhostCheckBox_CheckedChanged(object sender, EventArgs e)
        {
            if (localhostCheckBox.Checked)
            {
                hostTextBox.Text = "127.0.0.1";
                hostTextBox.ReadOnly = true;
            }
            else
            {
                hostTextBox.ReadOnly = false;
                hostTextBox.Select();
            }
        }

        void addButton_Click(object sender, EventArgs e)
        {
            if (ValidateForm())
            {
                vmrunGUIXmlWrapper guiXmlWrapper = new vmrunGUIXmlWrapper(_guiXmlPath);

                if (_hostName != null)
                {
                    guiXmlWrapper.RemoveHost(_hostName);

                    foreach (string guest in guiXmlWrapper.GetGuestsFromHost(_hostName))
                    {
                        guiXmlWrapper.SetGuestChildNodeInnerText(guest, _hostName, "host", nameTextBox.Text.Trim());
                    }
                }

                guiXmlWrapper.AddHost(nameTextBox.Text.Trim(), new vmrunInfoXmlWrapper().ConvertFriendlyNameToType(hostComboBox.Text), hostTextBox.Text.Trim(), portTextBox.Text.Trim(), argumentsTextBox.Text.Trim(), localhostCheckBox.Checked.ToString(), overrideCheckBox.Checked.ToString(), credentialsComboBox.Text);
                guiXmlWrapper.SaveXml();
                DialogResult importGuests = MessageBox.Show(String.Format("Would you like to query Guests on {0} for automatic import?", nameTextBox.Text.Trim()), "Automatic Guest Import", MessageBoxButtons.YesNo, MessageBoxIcon.Question);

                if (importGuests == DialogResult.Yes)
                {
                    GuestImport gi = new GuestImport(nameTextBox.Text.Trim(), credentialsComboBox.Text, _guiXmlPath, _vmrunPath);
                    gi.ShowDialog();
                }

                this.DialogResult = DialogResult.OK;
                this.Close();
            }
        }

        bool ValidateForm()
        {
            ep.Dispose();

            if (((nameTextBox.Text == null) || (nameTextBox.Text.Trim().Length == 0)) || (((_hostName == null) || (_hostName != nameTextBox.Text)) && (new vmrunGUIXmlWrapper(_guiXmlPath).HostExists(nameTextBox.Text.Trim()))))
            {
                ep.SetError(nameTextBox, "Please specify a unique name for this managed Host.");
                nameTextBox.Select();
                return false;
            }

            if (hostComboBox.SelectedIndex == -1)
            {
                ep.SetError(hostComboBox, "Please specify which type of Host you are adding.");
                hostComboBox.Select();
                return false;
            }

            if (hostGroupBox.Enabled)
            {
                if (credentialsComboBox.SelectedIndex == -1)
                {
                    ep.SetError(credentialsComboBox, "Please specify the Credentials that should be used to connect to this Host.");
                    credentialsComboBox.Select();
                    return false;
                }

                if ((hostTextBox.Enabled) && ((hostTextBox.Text == null) || (hostTextBox.Text.Trim().Length == 0)))
                {
                    ep.SetError(hostTextBox, "Please specify a Host name.");
                    hostTextBox.Select();
                    return false;
                }

                if ((portTextBox.Text == null) || (portTextBox.Text.Trim().Length == 0))
                {
                    ep.SetError(portTextBox, "Please specify a port for this Host.");
                    portTextBox.Select();
                    return false;
                }

                if ((argumentsTextBox.Text == null) || (argumentsTextBox.Text.Trim().Length == 0))
                {
                    ep.SetError(argumentsTextBox, "Please specify the connection arguments for this Host.");
                    argumentsTextBox.Select();
                    return false;
                }
            }

            return true;
        }

        void hostComboBox_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (hostComboBox.SelectedIndex > -1)
            {
                hostGroupBox.Enabled = false;
                localhostCheckBox.Checked = false;
                credentialsComboBox.Enabled = false;
                newCredentialsButton.Enabled = false;
                localhostCheckBox.Enabled = true;
                hostTextBox.Text = String.Empty;
                portTextBox.Text = String.Empty;
                argumentsTextBox.Text = String.Empty;
                vmrunInfoXmlWrapper infoXmlWrapper = new vmrunInfoXmlWrapper();

                if ((infoXmlWrapper.GetLocalFlag(hostComboBox.Text) == vmrunInfoXmlWrapper.LocalFlag.False) || (infoXmlWrapper.GetLocalFlag(hostComboBox.Text) == vmrunInfoXmlWrapper.LocalFlag.Optional))
                {
                    credentialsComboBox.Enabled = true;
                    newCredentialsButton.Enabled = true;
                    hostGroupBox.Enabled = true;
                    portTextBox.Text = infoXmlWrapper.GetDefaultPort(hostComboBox.Text);
                    overrideCheckBox.Checked = false;

                    if (infoXmlWrapper.GetLocalFlag(hostComboBox.Text) != vmrunInfoXmlWrapper.LocalFlag.False)
                    {
                        localhostCheckBox.Checked = true;
                    }
                    else
                    {
                        localhostCheckBox.Enabled = false;
                    }
                }

                hostComboBox.Select();
            }
            else
            {
                hostGroupBox.Enabled = false;
                credentialsComboBox.Enabled = false;
                newCredentialsButton.Enabled = false;
            }
        }

        void AddHost_Load(object sender, EventArgs e)
        {
            UpdateCredentialsList();

            foreach (string name in new vmrunInfoXmlWrapper().GetHostFriendlyNames())
            {
                hostComboBox.Items.Add(name);
            }

            if (_hostName != null)
            {
                vmrunGUIXmlWrapper guiXmlWrapper = new vmrunGUIXmlWrapper(_guiXmlPath);
                nameTextBox.Text = _hostName;
                hostComboBox.Text = new vmrunInfoXmlWrapper().ConvertTypeToFriendlyName(guiXmlWrapper.GetHostChildNodeInnerText(_hostName, "type"));
                credentialsComboBox.Text = guiXmlWrapper.GetHostChildNodeInnerText(_hostName, "credentials");
                localhostCheckBox.Checked = Convert.ToBoolean(guiXmlWrapper.GetHostChildNodeInnerText(_hostName, "localhost"));
                overrideCheckBox.Checked = Convert.ToBoolean(guiXmlWrapper.GetHostChildNodeInnerText(_hostName, "override"));
                hostTextBox.Text = guiXmlWrapper.GetHostChildNodeInnerText(_hostName, "host");
                portTextBox.Text = guiXmlWrapper.GetHostChildNodeInnerText(_hostName, "port");
                argumentsTextBox.Text = guiXmlWrapper.GetHostChildNodeInnerText(_hostName, "arguments");
            }
        }

        void BuildURL()
        {
            if (!overrideCheckBox.Checked)
            {
                if ((hostTextBox.Text != null) && (portTextBox.Text != null) && (hostTextBox.Text.Trim().Length > 0) && (portTextBox.Text.Trim().Length > 0))
                {
                    argumentsTextBox.Text = String.Format(new vmrunInfoXmlWrapper().GetConnectArgument(hostComboBox.Text), hostTextBox.Text, portTextBox.Text);
                }
                else
                {
                    argumentsTextBox.Text = String.Empty;
                }
            }
        }

        void UpdateCredentialsList()
        {
            credentialsComboBox.Items.Clear();

            foreach (string credentials in new vmrunGUIXmlWrapper(_guiXmlPath).GetCredentialsNames())
            {
                credentialsComboBox.Items.Add(credentials);
            }
        }
    }
}
